/**
 * @description 多个scrollview组件嵌套时，事件穿透组件
 * @date 2024.9.10
 * @author wz
 * @midify 2025.5.15
 * @editor wz
 */
import { Event, EventTouch } from 'cc';
import { _decorator, Component, Node, NodeEventType } from 'cc';
const { ccclass, property } = _decorator;

/**
 * ScrollView和ViewPage之前嵌套时候事件穿透组件
 */
@ccclass('CScrollThrough')
export default class CScrollThrough extends Component {
    private events: EventTouch[] = [];

    onLoad() {
        this.node.on(NodeEventType.TOUCH_START, this.onTouchHandle, this, true);
        this.node.on(NodeEventType.TOUCH_MOVE, this.onTouchHandle, this, true);
        this.node.on(NodeEventType.TOUCH_END, this.onTouchHandle, this, true);
        this.node.on(NodeEventType.TOUCH_CANCEL, this.onTouchHandle, this, true);
    }

    /**
     * 响应触摸事件
     * @param event 实际类型 EventTouch
     * @returns 
     */
    private onTouchHandle(event: any) {
        if (event.sham || event.simulate || event.target === this.node) return;

        let newEvent: any = new EventTouch(event.getTouches(), event.bubbles, event.type);
        newEvent.touch = event.touch;
        newEvent.sham = true;

        // 问：这里为啥不直接dispatchEvent
        // 答：必须让ScrollView把真的event先消耗掉，我们再发射假的才可以，
        // 可以去CCNode.js下找一个_doDispatchEvent函数，里面用到了_cachedArray这么个全局变量，
        // 先发射假的话，真的那个数据就被清空了
        this.events.push(newEvent);
    }

    update() {
        if (this.events.length === 0) return;
        for (let index = 0; index < this.events.length; index++) {
            this.node.dispatchEvent(this.events[index]);
        }
        this.events.length = 0;
    }
}


